use crate::error::AppError;
use crate::models::message::Message;
use crate::vo::validate_is_not_empty;
use jwt_simple::prelude::{Deserialize, Serialize};
use sqlx::FromRow;
use validator::Validate;

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, FromRow)]
pub struct MessageRes {
    pub id: i32,
    pub user_id: i32,
    pub chat_id: i32,
    pub content: String,
    pub files: String,
    #[serde(
        serialize_with = "crate::common::serialize",
        deserialize_with = "crate::common::deserialize"
    )]
    pub create_at: chrono::DateTime<chrono::Local>,
    #[serde(
        serialize_with = "crate::common::serialize",
        deserialize_with = "crate::common::deserialize"
    )]
    pub update_at: chrono::DateTime<chrono::Local>,
}

#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Validate)]
pub struct MessageReq {
    pub chat_id: i32,
    #[validate(custom(function = "validate_is_not_empty"))]
    pub content: String,

    pub files: String,
    #[serde(
        serialize_with = "crate::common::serialize",
        deserialize_with = "crate::common::deserialize"
    )]
    pub create_at: chrono::DateTime<chrono::Local>,
    #[serde(
        serialize_with = "crate::common::serialize",
        deserialize_with = "crate::common::deserialize"
    )]
    pub update_at: chrono::DateTime<chrono::Local>,
}

impl From<Message> for MessageRes {
    fn from(value: Message) -> Self {
        MessageRes {
            id: value.id,
            user_id: value.user_id,
            chat_id: value.chat_id,
            content: value.content,
            files: value.files,
            create_at: value.create_at,
            update_at: value.update_at,
        }
    }
}

impl TryFrom<MessageReq> for Message {
    type Error = AppError;

    fn try_from(value: MessageReq) -> Result<Self, Self::Error> {
        Ok(Message {
            id: 0,
            user_id: 0,
            chat_id: value.chat_id,
            content: value.content,
            files: value.files,
            create_at: value.create_at,
            update_at: value.update_at,
        })
    }
}
